﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


using System.IO;
using System.Threading;

using System.Collections.Specialized;
using System.Text.RegularExpressions;
using System.Collections;
using System.Net;
using System.Drawing.Imaging;


using System.Windows.Forms;
using Artisan.Server.Http;

namespace Artisan.Server
{
    public class ToolkitServer : HttpServer {

        private String _localUrl = "";
        /// <summary>
        /// 服务器目录
        /// </summary>
        public string ServerRoot { get; private set; }

        private string LocalSiteUrl()
        {

            if (String.IsNullOrEmpty(_localUrl))
            {
                string hostName = Dns.GetHostName();//本机名   
                System.Net.IPAddress[] addressList = Dns.GetHostByName(hostName).AddressList;//会警告GetHostByName()已过期，我运行时且只返回了一个IPv4的地址   
                                                                                             //System.Net.IPAddress[] addressList = Dns.GetHostAddresses(hostName);//会返回所有地址，包括IPv4和IPv6   
                                                                                             //foreach (IPAddress ip in addressList)  
                                                                                             //{
                IPAddress ip = addressList[0];
                String ipstr = ip.ToString();
                _localUrl = "http://" + ipstr + ":8989/";
            }
            return _localUrl;
        }

        public ToolkitServer(int port,String root)
            : base(port) {
            ServerRoot = root;

        }
        private void holderRequest(HttpProcessor p)
        {
            String requestURL = p.http_url;

            requestURL = requestURL.Replace("/", @"\").Replace("\\..", "").TrimStart('\\');
            requestURL = System.Web.HttpUtility.UrlDecode(requestURL, Encoding.UTF8);
            string requestFile = Path.Combine(ServerRoot, requestURL);

            //判断地址中是否存在扩展名
            string extension = Path.GetExtension(requestFile);

            //根据有无扩展名按照两种不同链接进行处
            if (extension != "")
            {
                //从文件中返回HTTP响应
                LoadFromFile(p, requestFile);
            }
            else
            {
                //目录存在且不存在index页面时时列举目录
                if (Directory.Exists(requestFile) && !File.Exists(requestFile + "\\index.html"))
                {
                    requestFile = Path.Combine(ServerRoot, requestFile);
                    var content = ListDirectory(requestFile, requestURL);
                    p.writeStringResponse(content);
                    
                }
                else
                {
                    //加载静态HTML页面
                    requestFile = Path.Combine(requestFile, "index.html");
                    LoadFromFile(p, requestFile);
                }
            }


        }

        /// <summary>
        /// 从文件返回一个HTTP响应
        /// </summary>
        /// <param name="fileName">文件名</param>
        private HttpProcessor LoadFromFile(HttpProcessor p, string fileName)
        {
            //获取文件扩展名以判断内容类型
            string extension = Path.GetExtension(fileName);

            //获取当前内容类型
            string contentType = MimeMapping.GetMimeMapping(fileName);

            //如果文件不存在则返回404否则读取文件内容
            if (!File.Exists(fileName))
            {
                p.writeStringResponse("<html><body><h1>404 - Not Found</h1></body></html>");

            }
            else
            {
                byte[] data = File.ReadAllBytes(fileName);
                p.writeBinary("HTTP/1.0", contentType, data.Length, "200 OK", data);
               
            }

            //返回数据
            return p;
        }

        private string ConvertPath(string[] urls)
        {
            string html = string.Empty;
            int length = ServerRoot.Length;
            foreach (var url in urls)
            {
                var s = url.StartsWith("..") ? url : url.Substring(length).TrimEnd('\\');
                html += String.Format("<li><a href=\"{0}\">{0}</a></li>", s);
            }

            return html;
        }

        private string ListDirectory(string requestDirectory, string requestURL)
        {
            //列举子目录
            var folders = requestURL.Length > 1 ? new string[] { "../" } : new string[] { };
            folders = folders.Concat(Directory.GetDirectories(requestDirectory)).ToArray();
            var foldersList = ConvertPath(folders);

            //列举文件
            var files = Directory.GetFiles(requestDirectory);
            var filesList = ConvertPath(files);

            //构造HTML
            StringBuilder builder = new StringBuilder();
            builder.Append(string.Format("<html><head><title>{0}</title></head>", requestDirectory));
            builder.Append(string.Format("<body><h1>{0}</h1><br/><ul>{1}{2}</ul></body></html>",
                 requestURL, filesList, foldersList));

            return builder.ToString();
        }

        public override void handleGETRequest (HttpProcessor p)
		{

            try
            {
                NameValueCollection nvc = new NameValueCollection();
                String baseUrl = "";
                ParseUrl(p.http_url, out baseUrl, out nvc);


                holderRequest(p);
                //p.writeSuccess();
                //p.outputStream.WriteLine("没有提交登录信息，无法继续操作。");

                // pluginManager.ProcessGet(p, nvc);
            }
            catch (Exception ex)
            {

            }


        }

        /// <summary>
        /// 分析 url 字符串中的参数信息
        /// </summary>
        /// <param name="url">输入的 URL</param>
        /// <param name="baseUrl">输出 URL 的基础部分</param>
        /// <param name="nvc">输出分析后得到的 (参数名,参数值) 的集合</param>
        /// <author>木野狐(Neil Chen)</author>
        /// <date>2005-06-23</date>
        static void ParseUrl(string url, out string baseUrl, out NameValueCollection nvc)
        {
            if (url == null)
                throw new ArgumentNullException("url");

            nvc = new NameValueCollection();
            baseUrl = "";

            if (url == "")
                return;

            int questionMarkIndex = url.IndexOf('?');

            if (questionMarkIndex == -1)
            {
                baseUrl = url;
                return;
            }
            baseUrl = url.Substring(0, questionMarkIndex);
            if (questionMarkIndex == url.Length - 1)
                return;
            string ps = url.Substring(questionMarkIndex + 1);

            // 开始分析参数对    
            Regex re = new Regex(@"(^|&)?(\w+)=([^&]+)(&|$)?", RegexOptions.Compiled);
            MatchCollection mc = re.Matches(ps);

            foreach (Match m in mc)
            {
                nvc.Add(m.Result("$2"), m.Result("$3"));
            }
        }
        static void ParseParams(String paramData, out NameValueCollection nvc)
        {
            nvc = new NameValueCollection();
            // 开始分析参数对    
            Regex re = new Regex(@"(^|&)?(\w+)=([^&]+)(&|$)?", RegexOptions.Compiled);
            MatchCollection mc = re.Matches(paramData);

            foreach (Match m in mc)
            {
                nvc.Add(m.Result("$2"), m.Result("$3"));
            }
        }
        //显示键，值  
        public static void PrintKeysAndValues(NameValueCollection myCol)
        {
            IEnumerator myEnumerator = myCol.GetEnumerator();
            Console.WriteLine("   KEY        VALUE");
            foreach (String s in myCol.AllKeys)
                Console.WriteLine("   {0,-10} {1}", s, myCol[s]);
            Console.WriteLine();
        }
        
        public override void handlePOSTRequest(HttpProcessor p, StreamReader inputData) {
            try{
                Console.WriteLine("POST request: {0}", p.http_url);
                string data = inputData.ReadToEnd();
                NameValueCollection nvc;

                ParseParams(data, out nvc);

                // 打印POST参数
                PrintKeysAndValues(nvc);

                holderRequest(p);

                //p.writeSuccess();
                //p.outputStream.WriteLine("没有提交登录信息，无法继续操作。");
                //p.outputStream.WriteLine(JsonConvert.SerializeObject(ReturnData.ErrorResult("没有提交登录信息，无法继续操作。")));
                return;

                // pluginManager.ProcessPost(p, nvc);

            }
            catch (Exception ex)
            {
                

            }
         
        }
        public override void handlePOSTRequestStream(HttpProcessor p, Stream stream)
        {
            throw new NotImplementedException();
        }
    }

    
}
